package com.dy.yunying.biz.service.ads.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dy.yunying.api.dto.MonitorRuleManagerDto;
import com.dy.yunying.api.entity.MonitorRuleManager;
import com.dy.yunying.api.entity.ParentGameDO;
import com.dy.yunying.api.enums.MonitorItemEnum;
import com.dy.yunying.api.enums.MonitorTargetTypeEnum;
import com.dy.yunying.api.req.MonitorRuleManagerReq;
import com.dy.yunying.api.req.ParentGameReq;
import com.dy.yunying.biz.dao.ads.MonitorRuleManagerMapper;
import com.dy.yunying.biz.exception.YunyingException;
import com.dy.yunying.biz.service.ads.MonitorRuleManagerService;
import com.dy.yunying.biz.service.manage.AdRoleUserService;
import com.dy.yunying.biz.service.manage.ParentGameService;
import com.pig4cloud.pig.admin.api.vo.UserSelectVO;
import com.pig4cloud.pig.api.entity.AdAccount;
import com.pig4cloud.pig.api.feign.RemoteAccountService;
import com.pig4cloud.pig.api.util.StringUtils;
import com.pig4cloud.pig.api.vo.AdAccountVo;
import com.pig4cloud.pig.common.core.constant.CommonConstants;
import com.pig4cloud.pig.common.core.constant.SecurityConstants;
import com.pig4cloud.pig.common.core.constant.enums.StatusEnum;
import com.pig4cloud.pig.common.core.util.NumberUtil;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.security.util.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.TreeSet;
import java.util.stream.Collectors;

/**
 * @Description: monitor_rule_manager
 * @Author: hma
 * @Date:   2023-03-17
 * @Version: V1.0
 */
@Service
public class MonitorRuleManagerServiceImpl extends ServiceImpl<MonitorRuleManagerMapper, MonitorRuleManager> implements MonitorRuleManagerService {


	@Autowired
	private ParentGameService  parentGameService;
	@Autowired
	private  RemoteAccountService remoteAccountService;
	@Autowired
	private AdRoleUserService adRoleUserService;

	/**
	 *查询监控规则列表
	 * @param managerDto
	 * @return
	 */
	@Override
	public R<IPage<MonitorRuleManager>> queryMonitorRules(MonitorRuleManagerReq managerDto) {
		try {
			Boolean admin=Boolean.FALSE;
			if (SecurityUtils.getRoles().contains(1)) {
				admin=Boolean.TRUE;
			}
			if(!admin){
				//非管理员 ，当没有选中用户的时候，可以查看自己，不存在为空
				List<UserSelectVO> resultList = adRoleUserService.getOwnerRoleUsers();
				if(CollectionUtils.isEmpty(resultList)){
					return  R.ok(new Page<MonitorRuleManager>());
				}
				managerDto.setUserArr(resultList.stream().map(m->m.getUserId().toString()).collect(Collectors.joining(",")) );
			}

			IPage<MonitorRuleManager> ruleManagerIPage = baseMapper.selectMonitorRuleList(managerDto);
			List<MonitorRuleManager> records = ruleManagerIPage.getRecords();
			if(!CollectionUtils.isEmpty(records)){
				dealData(records);

			}
			return R.ok(ruleManagerIPage, "查询成功");
		} catch (Exception e) {
			log.error("queryMonitorRules error:" + e.getMessage(), e);
			return R.failed("查询失败");
		}
	}

	private void dealData(List<MonitorRuleManager> records) throws Exception {
		ParentGameReq parentGameReq=new ParentGameReq();
		parentGameReq.setStatus(StatusEnum.TYPE_ONE.getStatus());
		List<Long>  list=new LinkedList<>();
		records.forEach(r->{
			if(StringUtils.isNotBlank(r.getMonitorGameId())){
				List<Long> gameIds = Arrays.asList(r.getMonitorGameId().split(",")).stream().map(s -> Long.parseLong(s.trim())).collect(Collectors.toList());
				list.addAll(gameIds);
			}

		});
		List<Long>  finalList=list;
		finalList=finalList.stream().distinct().collect(Collectors.toList());
		parentGameReq.setIds(finalList);
		List<ParentGameDO> pGameList = parentGameService.getCacheablePGameList(parentGameReq);
		AdAccountVo adAccountVo=new AdAccountVo();
		List<AdAccount> adAccountList=remoteAccountService.getAllList(adAccountVo,SecurityConstants.FROM_IN);
		for (MonitorRuleManager record : records) {
			String monitorGameId = record.getMonitorGameId();
			if(StringUtils.isEmpty(monitorGameId)){
				record.setMonitorGame("不限");
			}else{

				List<String> gameIdArr=Arrays.asList(monitorGameId.split(","));
				if(!CollectionUtils.isEmpty(pGameList)){
					List<ParentGameDO> filterGames=pGameList.stream().filter(g->gameIdArr.contains(g.getId().toString())).collect(Collectors.toList());
					record.setMonitorGame(filterGames.stream().map(m->m.getGname()).collect(Collectors.joining(",")) );
				}

			}
			String  adAccount = record.getAdAccount();
			if(StringUtils.isNotBlank(adAccount) && !CollectionUtils.isEmpty(adAccountList)){
				// 查询广告账号
				List<String> adAccountArr=Arrays.asList(adAccount.split(","));
				List<AdAccount> filterAccount=	adAccountList.stream().filter(a->adAccountArr.contains(a.getAdvertiserId())).collect(Collectors.toList());
				record.setMonitorAccountName(filterAccount.stream().map(m->m.getAdvertiserName()+"("+m.getAdvertiserId()+")").collect(Collectors.joining(",")) );

			}
			record.setMonitorTargetName(MonitorTargetTypeEnum.getOneByType(record.getMonitorTarget()).getName());
		}
	}


	/**
	 * 查询监控规则详情
	 * @param id
	 * @return
	 */
	@Override
	public R<MonitorRuleManager> getMonitorRuleManager(Integer id) {
		try {
			 List<MonitorRuleManager> list = baseMapper.selectList(new LambdaQueryWrapper<MonitorRuleManager>().eq(MonitorRuleManager::getId,id));
			 if(CollectionUtils.isEmpty(list)){
				 return  R.failed("当前规则不存在");
			 }
		     dealData(list);
			return R.ok(list.get(0), "查询成功");
		} catch (Exception e) {
			log.error("getMonitorRuleManager error:" + e.getMessage(), e);
			return R.failed("查询失败");
		}
	}

	/**
	 * 逻辑删除监控规则
	 * @param id
	 * @return
	 */
	@Override
	public R deleteMonitorRule(Integer id) {
		try {
			MonitorRuleManager updateManager=new MonitorRuleManager();
			updateManager.setId(id);
			updateManager.setUpdateTime(new Date());
			updateManager.setUpdateId(SecurityUtils.getUser().getId());
			updateManager.setDeleted( CommonConstants.DELETED_TRUE);
			if(this.updateById(updateManager) ){
				return R.ok().setMsg("删除成功");
			}else{
				return  R.failed("当前规则不存在");
			}

		} catch (Exception e) {
			log.error("deleteMonitorRule error:" + e.getMessage(), e);
			return R.failed("删除失败");
		}
	}


	/**
	 * 开启/关闭规则管理
	 * @param id
	 * @param monitorStatus
	 * @return
	 */
	@Override
	public R updateMonitorRuleStatus(Integer id, Integer monitorStatus) {
		try {
			MonitorRuleManager updateManager=new MonitorRuleManager();
			updateManager.setId(id);
			updateManager.setUpdateId(SecurityUtils.getUser().getId());
			updateManager.setUpdateTime(new Date());
			updateManager.setMonitorStatus(monitorStatus);
			if(this.updateById(updateManager)){
				return R.ok().setMsg("更新成功");
			}else{
				return  R.failed("当前规则不存在");
			}
		} catch (Exception e) {
			log.error("updateMonitorRuleStatus error:" + e.getMessage(), e);
			return R.failed("更新失败");
		}
	}


	/**
	 * 保存监控规则
	 * @param managerDto
	 * @return
	 */
	@Override
	public R saveMonitorRule(MonitorRuleManagerDto managerDto) {
		try {
			validateAdmonitorRule(managerDto);
			String monitorName=managerDto.getMonitorName();
			MonitorRuleManager monitorRuleManager = getOne(new LambdaQueryWrapper<MonitorRuleManager>().eq(MonitorRuleManager::getMonitorName,monitorName).eq(MonitorRuleManager::getDeleted,CommonConstants.DELETED_FALSE));
			if (Objects.nonNull(monitorRuleManager)) {
				throw new YunyingException("规则名称已存在【"+monitorName+"】");
			}
			MonitorRuleManager insertManager=new MonitorRuleManager();
			BeanUtils.copyProperties(managerDto,insertManager);
			insertManager.setRuleChange(CommonConstants.CHANGE_1);
			insertManager.setCreateId(SecurityUtils.getUser().getId());
			insertManager.setCreateTime(new Date());
			insertManager.setDeleted(CommonConstants.DELETED_FALSE);
			this.save(insertManager);
			return R.ok().setMsg("保存成功");
		} catch (YunyingException se) {
			return R.failed(se.getMessage());
		} catch (Exception e) {
			log.error("saveMonitorRule error:" + e.getMessage(), e);
			return R.failed("保存失败");
		}
	}

	/**
	 * 修改监控规则
	 * @param managerDto
	 * @return
	 */
	@Override
	public R updateMonitorRule(MonitorRuleManagerDto managerDto) {
		try {

			//监控游戏，排查计划，当用户设置为空的时候，对应将值设为空
			validateAdmonitorRule(managerDto);
			MonitorRuleManager monitorName = this.getOne(new LambdaQueryWrapper<MonitorRuleManager>().eq(MonitorRuleManager::getMonitorName, managerDto.getMonitorName()).eq(MonitorRuleManager::getDeleted,CommonConstants.DELETED_FALSE).notIn(MonitorRuleManager::getId,managerDto.getId()).last("limit 1"));
			if(Objects.nonNull(monitorName)) {
				return R.failed("规则名称已存在【"+managerDto.getMonitorName()+"】");
			}
			MonitorRuleManager currentManagerRule = this.getOne(new LambdaQueryWrapper<MonitorRuleManager>().eq(MonitorRuleManager::getId,managerDto.getId()));
			if(Objects.isNull(currentManagerRule)){
				return  R.failed("当前规则不存在");
			}
			MonitorRuleManager updateManager=new MonitorRuleManager();
			updateManager.setUpdateId(SecurityUtils.getUser().getId());
			updateManager.setUpdateTime(new Date());
			updateManager.setDeleted(CommonConstants.DELETED_FALSE);

			UpdateWrapper uw = new UpdateWrapper();
			if(StringUtils.isBlank(managerDto.getMonitorGameId())){
				uw.set("monitor_game_id", null);
			}else {
				uw.set("monitor_game_id", managerDto.getMonitorGameId());
			}
			if(StringUtils.isBlank(managerDto.getExceptPlan())){
				uw.set("except_plan", null);
			}else{
				uw.set("except_plan", managerDto.getExceptPlan());
			}
			uw.set("monitor_name",managerDto.getMonitorName());
			uw.set("monitor_channel_type",managerDto.getMonitorChannelType());
			uw.set("ad_account",managerDto.getAdAccount());
			uw.set("monitor_item",managerDto.getMonitorItem());
			uw.set("monitor_target",managerDto.getMonitorTarget());
			uw.set("compare",managerDto.getCompare());
			uw.set("compare_value",managerDto.getCompareValue());
			uw.set("notifytor",managerDto.getNotifytor());
			uw.eq("id", managerDto.getId());

			if(!compareRuleEqual(currentManagerRule,managerDto) ){
				//规则发生变更
				uw.set("rule_change",CommonConstants.CHANGE_1);
			}
			if(this.update(uw)){
				return R.ok(true, "保存成功");
			}else{
				return  R.failed("当前规则不存在");
			}
		} catch (YunyingException se) {
			return R.failed(se.getMessage());
		} catch (Exception e) {
			log.error("updateMonitorRule error:" + e.getMessage(), e);
			return R.failed("保存失败");
		}
	}


	/**
	 * 查询对应的规则是否发生变化（除名字外，其他有变更都算变化）
	 * @return
	 */
	private Boolean  compareRuleEqual(MonitorRuleManager currentManagerRule,MonitorRuleManagerDto updateDto ){
		Boolean  equalFlag=Boolean.TRUE;
		if(!currentManagerRule.getMonitorChannelType().equals(updateDto.getMonitorChannelType())){
			return Boolean.FALSE;
		}
		List<String> currentAccountArr=Arrays.asList(currentManagerRule.getAdAccount().split(","));
		List<String> updateAccountArr=Arrays.asList(updateDto.getAdAccount().split(","));
		List<String> minus= currentAccountArr.stream().filter(item -> !updateAccountArr.contains(item)).collect(Collectors.toList());
		if(!CollectionUtils.isEmpty(minus)){
			return Boolean.FALSE;
		}
		if(!currentManagerRule.getMonitorItem().equals(updateDto.getMonitorItem())){
			return Boolean.FALSE;
		}
		if(!currentManagerRule.getMonitorTarget().equals(updateDto.getMonitorTarget())){
			return Boolean.FALSE;
		}
		if(!StringUtils.isEquals(currentManagerRule.getCompare(),updateDto.getCompare())){
			return Boolean.FALSE;
		}
		if(new BigDecimal(currentManagerRule.getCompareValue()).compareTo(new BigDecimal(updateDto.getCompareValue())) == 1 ||  new BigDecimal(currentManagerRule.getCompareValue()).compareTo(new BigDecimal(updateDto.getCompareValue())) == -1 ){
			return Boolean.FALSE;
		}
		String  currentGameIds=currentManagerRule.getMonitorGameId();
		String   updateGameIds=updateDto.getMonitorGameId();
		if(StringUtils.isNotEmpty(currentGameIds)&& StringUtils.isNotEmpty(updateGameIds)){
			List<String> currentGameArr=Arrays.asList(currentGameIds.split(","));
			List<String> updateGameArr=Arrays.asList(updateGameIds.split(","));
			if(currentGameArr.size() != updateGameArr.size() ){
				return Boolean.FALSE;
			}
			List<String> minusGame= currentGameArr.stream().filter(item -> !updateGameArr.contains(item)).collect(Collectors.toList());
			if(!CollectionUtils.isEmpty(minusGame)){
				return Boolean.FALSE;
			}
		}else{
			//当其中一个为空，另外一个不为空
			if(StringUtils.isEmpty(currentGameIds)&&StringUtils.isNotEmpty(updateGameIds)){
				return Boolean.FALSE;
			}
			if(StringUtils.isNotEmpty(currentGameIds)&&StringUtils.isEmpty(updateGameIds)){
				return Boolean.FALSE;
			}


		}
		if(!currentManagerRule.getNotifyType().equals(updateDto.getNotifyType())){
			return Boolean.FALSE;
		}
		List<String> currentNotifytorArr=Arrays.asList(currentManagerRule.getNotifytor().split(","));
		List<String> updateNotifytorArr=Arrays.asList(updateDto.getNotifytor().split(","));
		if(currentNotifytorArr.size() != updateNotifytorArr.size() ){
			return Boolean.FALSE;
		}
		List<String> minusNotify= currentNotifytorArr.stream().filter(item -> !updateNotifytorArr.contains(item)).collect(Collectors.toList());
		if(!CollectionUtils.isEmpty(minusNotify)){
			return Boolean.FALSE;
		}

		String  currentExPlans=currentManagerRule.getExceptPlan();
		String   updateExPlans=updateDto.getExceptPlan();
		if(StringUtils.isNotBlank(currentExPlans)&& StringUtils.isNotBlank(updateExPlans) ){
			List<String> currentExPlanArr=Arrays.asList(currentExPlans.split(","));
			List<String> updateExPlanArr=Arrays.asList(updateExPlans.split(","));
			if(currentExPlanArr.size() != updateExPlanArr.size() ){
				return Boolean.FALSE;
			}
			List<String> minusExPlan= currentExPlanArr.stream().filter(item -> !updateExPlanArr.contains(item)).collect(Collectors.toList());
			if(!CollectionUtils.isEmpty(minusExPlan)){
				return Boolean.FALSE;
			}
		}else{
			//当其中一个为空，另外一个不为空
			if(StringUtils.isEmpty(currentExPlans)&&StringUtils.isNotEmpty(updateExPlans)){
				return Boolean.FALSE;
			}
			if(StringUtils.isNotEmpty(currentExPlans)&&StringUtils.isEmpty(updateExPlans)){
				return Boolean.FALSE;
			}


		}

		return equalFlag;



	}
	public void validateAdmonitorRule(MonitorRuleManagerDto managerDto) {
		// 验证长度，验证浮点型值
		if(managerDto.getMonitorName().length() > 20){
			throw new YunyingException("规则名称不允许超过20个字符长度");
		}
		if(managerDto.getCompareValue().length() > 20){
			throw new YunyingException("比较值不允许超过20个字符长度");
		}
		if(null !=managerDto.getCompareValue() && !NumberUtil.isNumeric(managerDto.getCompareValue())) {
			throw new YunyingException("比较值只能为数字");
		}
		if(MonitorItemEnum.ACCOUNT.getType().equals(managerDto.getMonitorItem())){
			//广告账户：游戏，排除计划不存在
			managerDto.setMonitorGameId(null);
			managerDto.setExceptPlan(null);

		}

	}




}
